﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Estimate.Common.Estimate;
using Estimate.Common.Estimate.EstimateValue;
using Estimate.Common.Repository;
using Estimate.Common.DBFieldTypes;
using Estimate.Common.Entity;
//using System.Text.RegularExpressions;

namespace Estimate.Common.Estimate
{
    /// <summary>
    /// 计算分级检验、累加降水、一般降水及暴雨以上、晴雨
    /// </summary>
    public class WaterScoreCalculate
    {
        /// <summary>
        /// 无意义的值
        /// </summary>
        public readonly static float NO_MEANS = 101f;

        public WaterScoreCalculate()
        {
           
        }

        #region 晴雨详细NA、NB、NC、ND
        public void PCDetail(WaterScore waterSore, WaterfallAmountInspectionResult WaterfallAmountInspection)
        {

            if (WaterfallAmountInspection == WaterfallAmountInspectionResult.EmptyForecast)
            {
                waterSore.EmptyForecast++;
                return;
            }
            if (WaterfallAmountInspection == WaterfallAmountInspectionResult.LackForecast)
            {
                waterSore.LackForecast++;
                return;
            }
            if (WaterfallAmountInspection == WaterfallAmountInspectionResult.ForecastError)
            {
                waterSore.ForecastError++;
                return;
            }
            if (WaterfallAmountInspection == WaterfallAmountInspectionResult.RealError)
            {
                waterSore.RealError++;
                return;
            }
            if (WaterfallAmountInspection == WaterfallAmountInspectionResult.Breakdown)
            {
                waterSore.Breakdown++;
                return;
            }
            if (WaterfallAmountInspection == WaterfallAmountInspectionResult.LackReal)
            {
                waterSore.LackReal++;
                return;
            }

            switch (WaterfallAmountInspection)
            {
                case WaterfallAmountInspectionResult.NA:
                    waterSore.NA++;
                    break;
                case WaterfallAmountInspectionResult.NB:
                    waterSore.NB++;
                    break;
                case WaterfallAmountInspectionResult.NC:
                    waterSore.NC++;
                    break;
                case WaterfallAmountInspectionResult.ND:
                    waterSore.ND++;
                    break;
                default:
                    waterSore.Breakdown++;
                    break;
            }
        }
        #endregion

        #region 分级详细NA、NB、NC、ND
        /// <summary>
        /// 分级详细NA、NB、NC、ND
        /// </summary>
        /// <param name="k">降雨级别</param>
        /// <param name="PrecipitationLevelInspection">分级降水检验</param>
        /// <param name="WaterfallAmountInspection">晴雨(雪)检验 </param>
        /// <param name="WaterfallLevelInspection">一般性降水检验</param>
        /// <param name="SumPrecipitationLevelInspection">累加降水量检验</param>

        public void TSDetail(WaterScore waterSore, int k, PrecipitationLevelInspectionResult PrecipitationLevelInspection)
        {
            if (PrecipitationLevelInspection == PrecipitationLevelInspectionResult.Breakdown)
            {
                waterSore.Breakdown++;
                return;
            }
            if (PrecipitationLevelInspection == PrecipitationLevelInspectionResult.ForecastError)
            {
                waterSore.ForecastError++;
                return;
            }
            if (PrecipitationLevelInspection == PrecipitationLevelInspectionResult.RealError)
            {
                waterSore.RealError++;
                return;
            }
            if (PrecipitationLevelInspection == PrecipitationLevelInspectionResult.LackForecast)
            {
                waterSore.LackForecast++;
                return;
            }
            if (PrecipitationLevelInspection == PrecipitationLevelInspectionResult.LackReal)
            {
                waterSore.LackReal++;
                return;
            }

            int smi = (int)PrecipitationLevelInspection;
            switch (k)
            {
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6: //从小雨到特大暴雨

                    if (smi == k)
                        waterSore.NA++;
                    else if (smi == k + 10)
                        waterSore.NB++;
                    else if (smi == k + 20)
                        waterSore.NC++;
                    else
                        waterSore.ND++;
                    break;
                case 8:
                case 9:
                case 10:
                case 11://从小雪到暴雪

                    if (smi == k - 1)
                        waterSore.NA++;
                    else if (smi == k + 9)
                        waterSore.NB++;
                    else if (smi == k + 19)
                        waterSore.NC++;
                    else
                        waterSore.ND++;
                    break;
            }


        }
        #endregion

        #region 一般性降水、暴雨TS详细NA、NB、NC、ND
        /// <summary>
        /// 一般性降水、暴雨TS详细NA、NB、NC、ND,
        /// </summary>
        /// <param name="k">10是一般性降水，11是暴雨以上</param>
        /// <returns></returns>
        public void NormalDetail(WaterScore waterSore, int k, WaterfallLevelInspectionResult WaterfallLevelInspection)
        {

            if (WaterfallLevelInspection == WaterfallLevelInspectionResult.Breakdown)
            {
                waterSore.Breakdown++;
                return;
            }
            if (WaterfallLevelInspection == WaterfallLevelInspectionResult.ForecastError)
            {
                waterSore.ForecastError++;
                return;
            }
            if (WaterfallLevelInspection == WaterfallLevelInspectionResult.RealError)
            {
                waterSore.RealError++;
                return;
            }
            if (WaterfallLevelInspection == WaterfallLevelInspectionResult.LackForecast)
            {
                waterSore.LackForecast++;
                return;
            }
            if (WaterfallLevelInspection == WaterfallLevelInspectionResult.LackReal)
            {
                waterSore.LackReal++;
                return;
            }
            if (WaterfallLevelInspection == WaterfallLevelInspectionResult.EmptyForecast)
            {
                waterSore.EmptyForecast++;
                return;
            }

            int smi = (int)WaterfallLevelInspection;

            if (smi == (k - 10) * 3 + 1)
                waterSore.NA++;
            else if (smi == (k - 10) * 3 + 2)
                waterSore.NB++;
            else if (smi == (k - 10) * 3 + 3)
                waterSore.NC++;
            else
                waterSore.ND++;
        }

        #endregion

        #region 累加降水量TS详细NA、NB、NC、ND
        /// <summary>
        /// 累加降水量TS详细NA、NB、NC、ND
        /// </summary>
        /// <param name="k"></param>
        /// <returns></returns>
        public void SumDetail(WaterScore waterSore, int k, SumPrecipitationLevelInspectionResult SumPrecipitationLevelInspection)
        {
            if (SumPrecipitationLevelInspection == SumPrecipitationLevelInspectionResult.Breakdown)
            {
                waterSore.Breakdown++;
                return;
            }
            if (SumPrecipitationLevelInspection == SumPrecipitationLevelInspectionResult.ForecastError)
            {
                waterSore.ForecastError++;
                return;
            }
            if (SumPrecipitationLevelInspection == SumPrecipitationLevelInspectionResult.RealError)
            {
                waterSore.RealError++;
                return;
            }
            if (SumPrecipitationLevelInspection == SumPrecipitationLevelInspectionResult.LackForecast)
            {
                waterSore.LackForecast++;
                return;
            }
            if (SumPrecipitationLevelInspection == SumPrecipitationLevelInspectionResult.LackReal)
            {
                waterSore.LackReal++;
                return;
            }
            if (SumPrecipitationLevelInspection == SumPrecipitationLevelInspectionResult.EmptyForecast)
            {
                waterSore.EmptyForecast++;
                return;
            }

            int smt = (int)SumPrecipitationLevelInspection;

            switch (k)
            {
                case 1:

                    if (smt != 4 && smt != 9 && smt != 14 && smt < 19)
                        waterSore.NA++;
                    else if (smt >= 20 && smt <= 23)
                        waterSore.NB++;
                    else if (smt == 4 || smt == 9 || smt == 14 || smt == 19)
                        waterSore.NC++;
                    else
                        waterSore.ND++;
                    break;
                case 2:

                    if ((smt >= 6 && smt <= 8) || (smt >= 11 && smt <= 13) || (smt >= 16 && smt <= 18))
                        waterSore.NA++;
                    else if ((smt >= 1 && smt <= 3) || (smt >= 21 && smt <= 23))
                        waterSore.NB++;
                    else if (smt == 5 || smt == 9 || smt == 10 || smt == 14 || smt == 15 || smt == 19)
                        waterSore.NC++;
                    else
                        waterSore.ND++;

                    break;
                case 3:

                    if ((smt >= 12 && smt <= 13) || (smt >= 17 && smt <= 18))
                        waterSore.NA++;
                    else if ((smt >= 2 && smt <= 3) || (smt >= 7 && smt <= 8) || (smt >= 22 && smt <= 23))
                        waterSore.NB++;
                    else if (smt == 10 || smt == 11 || smt == 14 || smt == 15 || smt == 16 || smt == 19)
                        waterSore.NC++;
                    else
                        waterSore.ND++;

                    break;
                case 4:

                    if (smt == 18)
                        waterSore.NA++;
                    else if (smt == 3 || smt == 8 || smt == 13 || smt == 23)
                        waterSore.NB++;
                    else if ((smt >= 15 && smt <= 17) || smt == 19)
                        waterSore.NC++;
                    else
                        waterSore.ND++;

                    break;
            }

        }

        #endregion

        /// <summary>
        /// FullInfoReport计算分级检验、累加降水、一般降水及暴雨以上、晴雨的方法
        /// </summary>
        /// <param name="precipitationWaterScore">分级检验分数字典</param>
        /// <param name="waterfallLevelWaterScore">一般降水及暴雨以上分数字典</param>
        /// <param name="sumPrecipitationWaterScore">累加降水分数字典</param>
        /// <param name="waterfallAmountWaterScore">晴雨分数字典</param>
        /// <param name="RecordCount">样本记录数字典</param>
        /// <param name="semi"></param>
        /// <param name="Span"></param>
        public void CalculateWaterScoreBySemiString(Dictionary<string,Dictionary<PrecipitationLevel, Dictionary<ForeSpanType, WaterScore>>> PrecipitationWaterScore,
                                                    Dictionary<string,Dictionary<WaterfallLevel, Dictionary<ForeSpanType, WaterScore>>> WaterfallLevelWaterScore,
                                                    Dictionary<string, Dictionary<SumPrecipitationLevel, Dictionary<ForeSpanType, WaterScore>>> SumPrecipitationWaterScore,
                                                    Dictionary<string, Dictionary<ForeSpanType, WaterScore>> WaterfallAmountWaterScore,
                                                    Dictionary<string, Dictionary<ForeSpanType, Dictionary<DateTime, int>>> RecordCount,
                                                    ForeEntity Semi,
                                                    ForeSpanType Span,
                                                    Dictionary<string, string> CityCodes,
                                                    Dictionary<DateTime, Dictionary<ForeClockType, Dictionary<ForeSendpointType, List<ScheduleEntity>>>> Schedules
                                                    )
        {
            if (Semi.Semi == "") return;

            //如果排班表不为空，则先检测当前记录是否与排班表对应
            if (Schedules != null)
            {
                if (!Schedules.ContainsKey(Semi.Date))
                    return ;
                if (!Schedules[Semi.Date].ContainsKey(Semi.Clock))
                    return ;
                if (!Schedules[Semi.Date][Semi.Clock].ContainsKey(Semi.Sendpoint))
                    return ;
            }

            //string yyyyMM = Semi.Date.ToString("yyyyMM");//semi的年月

            List<string> ItemsOfCountRecorded = new List<string>();//当前Semi中已经统计过样本的预报员或站

            foreach (string s in Semi.Semi.Split(new char[] { '|' }))
            {
                if (s.Trim().Length < 5)
                    continue;

                string[] oserial = s.Split(new char[] { ';' });

                if (oserial[0] == "58265" || oserial[0] == "58358")
                    continue;

                //由于 58248 镇江站已经取消，使用的是58252. 但是预报数据中一直使用的是58248
                //所以，将 镇江 站的站 手动修正为 58248
                if (oserial[0] == "58252")
                    oserial[0] = "58248";

                string FStNum = oserial[0];// 预报站号

                List<string> keys = new List<string>();

                if (CityCodes != null)
                {
                    if (!GlobalFunction.CitiesContains(keys, FStNum, CityCodes))
                        continue;
                }
                else if (Schedules != null)
                {
                    if (!GlobalFunction.SchedulesContains(keys, FStNum, Semi, Schedules))
                        continue;
                }


                if (keys.Count == 0)//keys.Count == 0时，指当前ForeEntity只能算一个样本，不分小semi统计
                    CalculateWaterScoreBySemiString( PrecipitationWaterScore,
                                                     WaterfallLevelWaterScore, 
                                                     SumPrecipitationWaterScore,
                                                     WaterfallAmountWaterScore,
                                                     RecordCount,
                                                     ItemsOfCountRecorded,
                                                     Span, Semi.Date, oserial, "");
                else
                {
                    foreach (string key in keys)
                    {
                        CalculateWaterScoreBySemiString(PrecipitationWaterScore,
                                                            WaterfallLevelWaterScore,
                                                            SumPrecipitationWaterScore,
                                                            WaterfallAmountWaterScore,
                                                            RecordCount,
                                                            ItemsOfCountRecorded,
                                                            Span, Semi.Date, oserial, key
                            //, pair.Value
                                                            );
                    }
                }
            }


        }

        /// <summary>
        /// 计算分级检验、累加降水、一般降水及暴雨以上、晴雨的方法
        /// </summary>
        /// <param name="precipitationWaterScore">分级检验分数字典</param>
        /// <param name="waterfallLevelWaterScore">一般降水及暴雨以上分数字典</param>
        /// <param name="sumPrecipitationWaterScore">累加降水分数字典</param>
        /// <param name="waterfallAmountWaterScore">晴雨分数字典</param>
        /// <param name="RecordCount">样本记录数字典</param>
        /// <param name="StationsOfSettedRecordCount">已经被记录样本的站点</param>
        /// <param name="yyyyMM">smei的日期:年月</param>
        /// <param name="Span"></param>
        /// <param name="oserial"></param>
        /// <param name="key">为站台编号或为预报员编号</param>
        /// <param name="station">当前需要被记录样本的站点</param>
        private void CalculateWaterScoreBySemiString( Dictionary<string, Dictionary<PrecipitationLevel, Dictionary<ForeSpanType, WaterScore>>> PrecipitationWaterScore,
                                                      Dictionary<string, Dictionary<WaterfallLevel, Dictionary<ForeSpanType, WaterScore>>> WaterfallLevelWaterScore,
                                                      Dictionary<string, Dictionary<SumPrecipitationLevel, Dictionary<ForeSpanType, WaterScore>>> SumPrecipitationWaterScore,
                                                      Dictionary<string, Dictionary<ForeSpanType, WaterScore>> WaterfallAmountWaterScore,
                                                      Dictionary<string, Dictionary<ForeSpanType, Dictionary<DateTime, int>>> RecordCount,
                                                      List<string> ItemsOfCountRecorded,
                                                      ForeSpanType Span,
                                                      DateTime date,
                                                      string[] oserial,
                                                      string key
                                                      //string station
                                                    )
        {
           
             PrecipitationLevelInspectionResult PrecipitationLevelInspection = (PrecipitationLevelInspectionResult)Enum.Parse(typeof(PrecipitationLevelInspectionResult), oserial[1]);// 分级降水检验
             WaterfallAmountInspectionResult WaterfallAmountInspection = (WaterfallAmountInspectionResult)Enum.Parse(typeof(WaterfallAmountInspectionResult), oserial[2]);// 晴雨(雪)检验 
             WaterfallLevelInspectionResult WaterfallLevelInspection = (WaterfallLevelInspectionResult)Enum.Parse(typeof(WaterfallLevelInspectionResult), oserial[3]);// 一般性降水检验
             SumPrecipitationLevelInspectionResult SumPrecipitationLevelInspection = (SumPrecipitationLevelInspectionResult)Enum.Parse(typeof(SumPrecipitationLevelInspectionResult), oserial[4]);// 累加降水量检验



             #region 计算分级检验
             if (PrecipitationWaterScore != null)
                 foreach (PrecipitationLevel level in Enum.GetValues(typeof(PrecipitationLevel)))
                 {
                     if ((int)level < 1 || (int)level == 7) continue;//除故障和无降水的情况，并排除雨夹雪情况
                     TSDetail(PrecipitationWaterScore[key][level][Span], (int)level, PrecipitationLevelInspection);
                 }
             #endregion

             #region 计算累加降水
             if (SumPrecipitationWaterScore != null)
                 foreach (SumPrecipitationLevel level in Enum.GetValues(typeof(SumPrecipitationLevel)))
                 {
                     if ((int)level < 1) continue;//除故障和无降水的情况，并排除雨夹雪情况
                     SumDetail(SumPrecipitationWaterScore[key][level][Span], (int)level, SumPrecipitationLevelInspection);
                 }
             #endregion

             #region 计算一般降水及暴雨以上
             if (WaterfallLevelWaterScore != null)
                 foreach (WaterfallLevel level in Enum.GetValues(typeof(WaterfallLevel)))
                 {
                     if ((int)level < 1) continue;//除故障和无降水的情况，并排除雨夹雪情况
                     NormalDetail(WaterfallLevelWaterScore[key][level][Span], (int)level, WaterfallLevelInspection);
                 }
             #endregion

             #region 计算晴雨
             if (WaterfallAmountWaterScore != null)
                 PCDetail(WaterfallAmountWaterScore[key][Span], WaterfallAmountInspection);
             #endregion

             #region 记录样本数
             if (RecordCount != null)
             {
                 if (!ItemsOfCountRecorded.Contains(key))
                 {
                     ItemsOfCountRecorded.Add(key);
                
                     //一个semi记录中相同站点列表只能记录一次RecordCount
                     GlobalFunction.SetRecordCount(RecordCount, key, Span, date, 1);
                     //StationsOfSettedRecordCount.Add(station);
                 }
             }
             #endregion

        }
        



    }
}
